#include <HAL/deviceManager.h>
#include <utitl/logger.h>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>

#include <vector>
#include <iostream>
#include <string>

using namespace boost::property_tree;
using namespace boost::property_tree::xml_parser;

#define XML_PATH ("/opt/ECG/include/device/device.xml")

namespace ECG
{

namespace HAL
{
    DevManagerPtr DevManager::m_devManager;

    DevManagerPtr DevManager::instance()
    {
        if(!m_devManager.get())
        {
            m_devManager.reset(new DevManager(XML_PATH));
        }
        return m_devManager;
    }

    void DevManager::setConfigurePath(std::string path)
    {
        confPath = path;
    }

    bool DevManager::loadDevice()
    {
        // parse xml file
        try
        {
            log_debug() << "xml path: " << confPath;
            read_xml(confPath,rootTree);
        }catch(xml_parser_error e)
        {
            std::cout << e.what()<< std::endl;
            return false;
        }
        std::size_t devSize = rootTree.size();
        if(! devSize)
        {
            std::cout << "the empty tree" << std::endl;
            return false;
        }
        log_debug() << "child device size: " << devSize;
        
        BOOST_FOREACH(ptree::value_type &dev,rootTree.get_child("root"))
        {
            if(dev.first == "device")
            {
                /*
                BOOST_FOREACH(ptree::value_type &val , devs.second)
                {
                    if(v2.first == "HWConf")
                    {
                        // parse hwconf

                    }else // other value
                    {
                        log_debug() << val.second.data();
                    }
                }
                */
                std::string name = dev.second.get<std::string>("name");
                std::string ID = dev.second.get<std::string>("ID");
                std::string devpath = dev.second.get<std::string>("path");
                std::string outVar = dev.second.get<std::string>("outVar");
                std::string FilterID = dev.second.get<std::string>("FilterID");
                ptree &hwconf = dev.second.get_child("HWConf");

                log_debug() << "name = " << name << ", ID = " <<ID \
                << ", path = " << devpath << ", outVar = " << outVar << \
                ", FilterID = " << FilterID;
                DevicePtr device(new Device(hwconf,devpath,outVar,name));
                device->setID(ID);
                device->setFilterID(FilterID);

                devVec.push_back(device);
                log_debug() << "push vector ok";
            }else
            {
                std::cout << "err, can not find device node" << std::endl;
                return false;
            }
        }

        log_debug() << "pares xml file over";
        return true;
        
    }

    DevManager::DevManager(std::string xmlPath)
    {
        confPath = xmlPath;
    }

    DevManager::~DevManager()
    {

    }

    bool DevManager::mkDevInstanc()
    {
        return true;
    }


}

}